<template>
  <div class="component-library" :style="cssObj">

    <div class="toolbar">
      <div class="float-left">
        <!--<Input size="small"/>-->
      </div>
      <div class="float-right">
        <!--<Tooltip transfer content="刷新" placement="bottom">
          <Button size="small" type="primary"><Icon type="md-refresh"/></Button>
        </Tooltip>-->
        <Tooltip :max-width="250"
                 content="单击卡片可以快捷添加组件至画布中，您也可以拖拽某个卡片到画布中，将组件添加在画布中的某个位置（注意：拖拽添加组件需要画布处于可放置状态，点击画布空白区域或者左侧结构树顶部的【画布】即可激活画布的可放置状态）"
                 placement="bottom-start">
          <Icon type="md-help-circle" size="16"/>
        </Tooltip>
      </div>
      <div class="clearfix"></div>
    </div>

    <div class="search-result-wrap">

    </div>

    <div class="library-body">
      <div class="type-list">
        <div class="type-item" :class="{'active': type.id == customTypeId}"
             v-for="type in componentTypes"
             :key="type.id" @click="typeItemClickHandler(type.id)">
          <Tooltip :content="type.name" :disabled="type.name.length <= 2" placement="left">
            <Icon :custom="'iconfont ' + type.icon" size="16"/>
            <p class="name">{{$PnUtil.cutString(type.name, 2)}}</p>
          </Tooltip>
        </div>
        <div class="type-item" :class="{'active': enshrinePanelVisible}"
             @click="openEnshrinePanel">
          <Tooltip :content="'收藏组件'" placement="left">
            <Icon type="md-star" size="20"/>
            <p class="name">收藏</p>
          </Tooltip>
        </div>
      </div>
      <div class="component-collapse-wrap">

        <!-- 默认布局块 -->
        <div style="margin: 10px;" class="comp-card full-width" :data-component="'DefaultLayoutItem'" @click.stop="addCompToCanvas({name: 'DefaultLayoutItem'})">
          <div class="comp-card-header">
            <img src="../../../../assets/image/thumbnail/DefaultLayoutItem.png" :onerror="defaultImg"/>
          </div>
          <div class="comp-card-body">
            <p>布局块</p>
          </div>
        </div>

        <Collapse v-if="!enshrinePanelVisible" simple :value="componentCollapseValue">
          <Panel :name="collapseItem.name" v-for="(collapseItem, index) in componentCollapseList" :key="index">
            {{collapseItem.name ? collapseItem.name:'全部'}}（{{collapseItem.compinfos.length}}）
            <div slot="content">
              <Row>
                <i-col span="12" v-for="(compinfo, index) in collapseItem.compinfos" :key="index">
                  <div class="comp-card" :title="compinfo.alias_name"
                       :data-component="compinfo.name" @click.stop="addCompToCanvas(compinfo)">
                    <div class="comp-card-header">
                      <img :src="thumbnailPath(compinfo.thumbnail_uri)" :onerror="defaultImg"/>
                    </div>
                    <div class="comp-card-body">
                      <p>{{compinfo.alias_name | compNameFilter}}</p>
                    </div>
                  </div>
                </i-col>
              </Row>
            </div>
          </Panel>
        </Collapse>
        <!-- 收藏组件列表 -->
        <div v-else class="enshrine-panel">

          <div class="search-container">
            <Input size="small" v-model="searchEnshrineCompInputValue" search enter-button placeholder="输入名称搜索"
                   @on-search="searchEnshrineCompClickHandler"/>
          </div>
          <Collapse v-if="searchEnshrineCompResult.length == 0" simple accordion :value="enshrineCompCollapseValue">
            <Panel :name="collapseItem.id" :title="collapseItem.remark"
                   v-for="(collapseItem, index) in enshrineCompCollapseList" :key="index">
              <span :title="collapseItem.group_name">{{$PnUtil.cutString(collapseItem.group_name, 8)}}（{{collapseItem.enshrineComps.length}}）</span>
              <div slot="content">
                <Row>
                  <i-col span="12" v-for="ec in collapseItem.enshrineComps" :key="ec.id">
                    <div class="comp-card enshrine-comp-card" :title="ec.enshrine_name + '【描述：' + ec.remark + '】'"
                         :data-id="ec.id" :data-type="ec.type" :data-component="ec.component_name" @click.stop="addCompToCanvas(ec)">
                      <div class="comp-card-header">
                        <img :src="thumbnailPath(ec.thumbnail_uri)" :onerror="defaultImg"/>
                      </div>
                      <div class="comp-card-body">
                        <p>{{ec.enshrine_name | compNameFilter}}</p>
                      </div>
                    </div>
                  </i-col>
                </Row>
              </div>
            </Panel>
          </Collapse>
          <div v-else class="search-result-container">
            <Row>
              <i-col span="12" v-for="ec in searchEnshrineCompResult" :key="ec.id">
                <div class="comp-card" :title="ec.enshrine_name + '【描述：' + ec.remark + '】'"
                     :data-id="ec.id" :data-component="ec.component_name" @click.stop="addCompToCanvas(ec)">
                  <div class="comp-card-header">
                    <img :src="thumbnailPath(ec.thumbnail_uri)" :onerror="defaultImg"/>
                  </div>
                  <div class="comp-card-body">
                    <p>{{ec.enshrine_name | compNameFilter}}</p>
                  </div>
                </div>
              </i-col>
            </Row>
          </div>

        </div>
      </div>
    </div>

    <div class="along-comp-edit-model-mask-layer" v-if="isAlongCompEditModel"></div>

  </div>
</template>

<script>
  import _ from 'lodash';

  import {COL_NUM, LAYOUT_ITEM_W} from '@/utils/ReactiveDesignerCommonUtil'

  import { createHelpers } from 'vuex-map-fields';

  const { mapFields } = createHelpers({
    getterType: 'designer/getField',
    mutationType: 'designer/updateField',
  });

  export default {
    name: 'ComponentLibrary',
    props: {
      cssObj: {
        type: Object
      }
    },
    data() {
      return {
        componentTypes: [],
        customTypeId: '',
        componentCollapseValue: '',
        componentCollapseList: [],

        enshrinePanelVisible: false,
        enshrineCompCollapseValue: '',
        enshrineCompCollapseList: [],
        enshrineComps: [],
        searchEnshrineCompInputValue: '',
        searchEnshrineCompResult: []
      }
    },
    mounted() {

      this.loadComponentTypes();

      this.$EventBus.$on('pn_saveEnshrineSuccess', () => {
        this.searchEnshrineCompInputValue = '';
        this.searchEnshrineCompResult = [];
        this.openEnshrinePanel()
      })
    },
    methods: {

      /**
       * 加载所有组件分组
       */
      loadComponentTypes() {
        this.$PnApi.CompinfoApi.getAllCompinfoType().then(result => {
          this.componentTypes = result.data.payload;
          this.typeItemClickHandler(this.componentTypes[0].id)
        })
      },

      async loadComponentCollapseList(typeId) {
        this.componentCollapseList = [];
        return await this.$PnApi.CompinfoApi.getAllCompinfoByTypeId(typeId).then(result => {
          let allComponents = result.data.payload;
          let map = {};
          for (let i = 0; i < allComponents.length; i++) {
            let compinfo = allComponents[i];
            if (!map[compinfo.classify]) {
              this.componentCollapseList.push({
                name: compinfo.classify,
                compinfos: [compinfo]
              });
              map[compinfo.classify] = compinfo
            } else {
              for (let j = 0; j < this.componentCollapseList.length; j++) {
                let collapseItem = this.componentCollapseList[j];
                if (collapseItem.name == compinfo.classify) {
                  collapseItem.compinfos.push(compinfo);
                  break;
                }
              }
            }
          }
        });
      },

      async loadEnshrineCompCollapseList() {
        this.enshrineCompCollapseList = [];
        return await this.$PnApi.EnshrineCompApi.buildEnshrineCompLibrary().then(result => {
          this.enshrineCompCollapseList = result.data.payload;
        })
      },

      openEnshrinePanel() {
        this.customTypeId = '';
        this.enshrinePanelVisible = true;
        this.loadEnshrineCompCollapseList().then(result => {
          // this.enshrineCompCollapseValue = this.enshrineCompCollapseList[0].id;
          this.registerComponentLibraryDrag()
        })
      },

      typeItemClickHandler(typeId) {
        this.customTypeId = typeId;
        this.enshrinePanelVisible = false;
        this.componentCollapseValue = '';
        this.enshrineCompCollapseValue = '';
        this.loadComponentCollapseList(typeId).then(result => {
          this.componentCollapseValue = this.componentCollapseList[0].name;
          this.registerComponentLibraryDrag()
        })
      },

      addCompToCanvas (compinfo) {
        if (compinfo.name == 'DefaultLayoutItem') {
          let newLayoutItem = null
          if (this.pageMetadata.develop_canvas == 'AbsoluteLayoutCanvas') {
            newLayoutItem = this.$DesignerCommonUtil.buildAbsoluteLayoutItem();
            newLayoutItem.layoutItemConfigData.left = 20;
            newLayoutItem.layoutItemConfigData.top = 20;
          }else if (this.pageMetadata.develop_canvas == 'ReactiveLayoutCanvas') {
            newLayoutItem = this.$ReactiveDesignerCommonUtil.buildReactiveLayoutItem(
                (this.layoutItems.length * LAYOUT_ITEM_W) % COL_NUM,
                this.layoutItems.length + COL_NUM
            );
          }
          this.$store.commit('designer/addLayoutItem', newLayoutItem);
          this.$store.commit('designer/setCurrentSelectLayoutItemId', newLayoutItem.id);
        }else {
          if (compinfo.enshrine_name != undefined) {

            if (this.pageMetadata.develop_canvas == 'AbsoluteLayoutCanvas') {
              this.$PnApi.EnshrineCompApi.getLayoutItemObjById(compinfo.id).then(result => {
                let newLayoutItem = JSON.parse(result.data.payload);
                let type = compinfo.type;
                // 如果type='F'说明收藏的是普通功能组件
                if (type && type == 'F') {
                  newLayoutItem.id = this.$PnUtil.uuid();
                  if (newLayoutItem.component.id) {
                    newLayoutItem.component.id = this.$PnUtil.uuid()
                  }
                  newLayoutItem.layoutItemConfigData.left = 20;
                  newLayoutItem.layoutItemConfigData.top = 20;
                  this.$store.commit('designer/setRightSidebarFuncCompConfigFormName', '');
                  this.$store.commit('designer/addLayoutItem', newLayoutItem);
                  this.$store.commit('designer/setCurrentSelectLayoutItemId', newLayoutItem.id);
                  if (newLayoutItem.component.id) {
                    this.$store.commit('designer/setRightSidebarFuncCompConfigFormName', newLayoutItem.component.name + 'Form');
                  }
                }
                // 如果type='G'说明收藏的是组
                else if (type && type == 'G') {
                  let groupItem = newLayoutItem.groupItemObj;
                  let layoutItems = newLayoutItem.layoutItemObjs;
                  // 记录所有布局块基于组坐标的偏移位置
                  let offsetInfoArr = [];
                  // 组在收藏时保存的坐标位置
                  let groupItemOriginalPosition = {
                    left: groupItem.groupItemConfigData.left,
                    top: groupItem.groupItemConfigData.top
                  };
                  // 遍历被收藏的组关联的所有布局块，然后记录各自基于组原始坐标的位置偏移
                  layoutItems.forEach(layoutItem => {
                    let offsetInfo = {
                      layoutItemId: layoutItem.id,
                      offsetLeft: layoutItem.layoutItemConfigData.left - groupItemOriginalPosition.left,
                      offsetTop: layoutItem.layoutItemConfigData.top - groupItemOriginalPosition.top
                    };
                    offsetInfoArr.push(offsetInfo)
                  });

                  let newLayoutItemIds = [];
                  let newGroupItem = groupItem;
                  newGroupItem.groupItemConfigData.left = 20;
                  newGroupItem.groupItemConfigData.top = 20;
                  layoutItems.forEach(layoutItem => {
                    let offsetInfo = _.find(offsetInfoArr, {layoutItemId: layoutItem.id});
                    layoutItem.layoutItemConfigData.left = newGroupItem.groupItemConfigData.left + offsetInfo.offsetLeft;
                    layoutItem.layoutItemConfigData.top = newGroupItem.groupItemConfigData.top + offsetInfo.offsetTop;
                    let newId = this.$PnUtil.uuid();
                    newLayoutItemIds.push(newId);
                    layoutItem.id = newId;
                    if (layoutItem.component.id) {
                      layoutItem.component.id = this.$PnUtil.uuid()
                    }
                    this.$store.commit('designer/addLayoutItem', layoutItem);
                  });

                  newGroupItem.id = this.$PnUtil.uuid();
                  newGroupItem.layoutItemIds = newLayoutItemIds;
                  this.$store.commit('designer/addLayoutGroupItem', newGroupItem);
                  this.$store.commit('designer/setRightSidebarFuncCompConfigFormName', '');
                  this.$store.commit('designer/setCurrentSelectGroupItemId', newGroupItem.id);
                }
              })
            }else if (this.pageMetadata.develop_canvas == 'ReactiveLayoutCanvas') {
              this.$Message.warning('响应式栅格布局中，暂不支持添加收藏组件')
            }

          }else {
            let baseAttr = this.$PnUtil.getCompBaseAttr(compinfo.name);
            let newLayoutItem = null;
            if (this.pageMetadata.develop_canvas == 'AbsoluteLayoutCanvas') {
              newLayoutItem = this.$DesignerCommonUtil.buildAbsoluteLayoutItem();
              newLayoutItem.layoutItemConfigData.left = 20;
              newLayoutItem.layoutItemConfigData.top = 20;
            }else if (this.pageMetadata.develop_canvas == 'ReactiveLayoutCanvas') {
              newLayoutItem = this.$ReactiveDesignerCommonUtil.buildReactiveLayoutItem(
                  (this.layoutItems.length * LAYOUT_ITEM_W) % COL_NUM,
                  this.layoutItems.length + COL_NUM
              );
            }
            let component = {
              id: this.$PnUtil.uuid(),
              name: compinfo.name,
              version: baseAttr.version,
              compConfigData: Object.assign({}, this.$PnUtil.deepClone(this.$PnUtil.getCompConfigData(compinfo.name)))
            };
            newLayoutItem.component = component;
            this.$store.commit('designer/setRightSidebarFuncCompConfigFormName', '');
            this.$store.commit('designer/addLayoutItem', newLayoutItem);
            this.$store.commit('designer/setCurrentSelectLayoutItemId', newLayoutItem.id);
            if (newLayoutItem.component.id) {
              this.$store.commit('designer/setRightSidebarFuncCompConfigFormName', newLayoutItem.component.name + 'Form');
            }
          }
        }
      },

      async searchEnshrineComp (enshrine_name) {
        return await this.$PnApi.EnshrineCompApi.searchEnshrineComp(enshrine_name).then(result => {
          this.searchEnshrineCompResult = result.data.payload;
        })
      },

      searchEnshrineCompClickHandler(value) {
        if (value) {
          this.searchEnshrineComp(value).then(result => {
            this.registerComponentLibraryDrag()
          })
        }else {
          this.searchEnshrineCompResult = [];
          this.openEnshrinePanel()
        }
      },

      registerComponentLibraryDrag() {
        if ($('.comp-card').draggable()) {
          $('.comp-card').draggable('destroy');
        }
        $('.comp-card').draggable({
          zIndex: 999,
          revert: "invalid",
          helper: 'clone',
          containment: 'body',
          appendTo: 'body',
          scope: 'compCardScope'
        });
      },

      thumbnailPath(thumbnail_uri) {
        if (thumbnail_uri) {
          try {
            return require('../../../../components/functional/' + thumbnail_uri)
          } catch (e) {
            return ''
          }
        } else {
          return ''
        }
      }

    },
    computed: {
      ...mapFields({
        pageMetadata: 'pageMetadata',
        layoutItems: 'pageMetadata.layout.layoutItems',
        isAlongCompEditModel: 'isAlongCompEditModel'
      }),
      defaultImg() {
        return 'this.src="' + require('@/assets/image/thumbnail/thumbnail-default.png') + '";this.onerror=null'
      }
    },
    filters: {
      compNameFilter (value) {
        return _.truncate(value, {
          length: 6,
          omission: '...'
        })
      }
    }
  }
</script>

<style scoped>
  >>> .ivu-collapse > .ivu-collapse-item > .ivu-collapse-content {
    padding: 10px 10px 0px 10px !important;
  }
</style>

<style lang="less" scoped>

  .component-library {
    width: 100%;
    height: 100%;
    overflow: hidden;
    -moz-user-select: none;
    -webkit-user-select: none;
    user-select: none;

    .toolbar {
      height: 33px;
      line-height: 31px;
      padding: 0px 5px;
      background-color: #616161;
      border-bottom: 1px solid #424242;
    }

    .search-result-wrap {
      width: 100%;
      height: calc(100% - 33px);
      position: absolute;
      left: 0px;
      bottom: 0px;
      background-color: #bdbdbd;
      z-index: 4000;
      display: none;
    }

    .library-body {
      width: 100%;
      height: calc(100% - 33px);

      .type-list {
        width: 50px;
        height: 100%;
        background-color: rgba(33,33,33,.5);
        border-right: 1px solid #424242;
        float: left;
        overflow-x: hidden;
        scrollbar-width: none;

        &::-webkit-scrollbar {
          display: none;
        }

        .type-item {
          width: 100%;
          height: 55px;
          text-align: center;
          //line-height: 48px;
          padding-top: 5px;
          color: #fff;
          cursor: pointer;
          display: flex;
          justify-content: center;
          align-items: center;

          .name {
            white-space: nowrap;
            overflow: hidden;
            text-overflow: ellipsis;
          }

          &.active {
            background-color: #212121;
            border-right: 3px solid #2196f3;
          }

          &:hover {
            background-color: #212121;
          }
        }
      }

      .component-collapse-wrap {
        width: calc(100% - 50px);
        height: 100%;
        float: left;
        background-color: rgba(33,33,33,.2);
        overflow-x: hidden;
        scrollbar-width: none;

        &::-webkit-scrollbar {
          display: none;
        }

        .enshrine-panel {
          padding: 0px 0px 10px 0px;

          .search-container {
            width: 100%;
            height: 40px;
            background-color: #616161;
            padding: 7px 10px 0px 10px;
          }

          .search-result-container {
            padding: 10px;
          }
        }
      }
    }
  }

  .comp-card {
    width: 80px;
    height: auto;
    background-color: #616161;
    cursor: move;
    word-break: break-all;
    margin-bottom: 5px;
    z-index: 3000;
    border: 2px solid #424242;
    &:last-child {
      margin-bottom: 0px;
    }
    &.full-width {
      width: 160px
    }
    &:hover {
      border: 2px solid #2196f3;
    }
    .comp-card-header {
      width: 100%;
      height: 50px;
      text-align: center;
      background-color: #0D2B43;
      padding: 5px 0px;
      position: relative;
      img {
        width: 76px;
        height: auto;
        max-width: 100%;
        max-height: 100%;
        position: absolute;
        top: 50%;
        left: 50%;
        transform: translate(-50%,-50%);
      }
    }

    .comp-card-body {
      padding: 2px;
      text-align: center;
      p {
        color: #fff;
      }
    }
  }
</style>
